/*
*
* 一个用于渲染鹰眼世界的基础类 HawkWorld.js
*
* Daniel
*
* 2018.06.06
*
* */
define(function () {
    
    var hawkW = function(){
        
        this.scene = new THREE.Scene();
        this.camera = {};                   //主相机
        this.container = {};
        this.cameraCopy = {};               //联动相机.000000000000
        this.targetArr = [];
        this.enable = true;
        this.temporary = {
            objName: [],
            object: undefined,
            color: {}
        };
        this.orientation = {};
        this.way = "http://www.klbim.cn:8084/Engine/3d/texture/hawkeye/";
    };
    
        hawkW.prototype.init = function(domId,outCamera,tween){
            
            if(domId == undefined)return;
            var scope = this;
            var container = document.createElement("div");
            var body = document.getElementById(domId);
            var scene = this.scene;
            var camera;
            var renderer = new THREE.WebGLRenderer({alpha:true,antialias:true});
            
            
            this.container =  container ;
            this.camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 1, 500 );
            this.camera.position.set(0,0,12);
            this.cameraCopy = outCamera;
            this.tween = tween || {};
            this.camera.hawk = true;
            this.origin = {
                haw:new THREE.Vector3(0,0,12),
                scene: this.cameraCopy.position.clone()
            };
            this.camera.looks = new THREE.Vector3();
            camera = this.camera;
            //鹰眼样式
            container.style.width = "185px";
            container.style.height = "185px";
            container.style.position = "absolute";
            container.style.opacity = 0.7;
            container.style.top = "20px";
            container.style.right = "20px";
            container.id = "Hawk";
            
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( container.clientWidth, container.clientHeight );
            body.appendChild( container );
            container.appendChild( renderer.domElement );
            
            window.addEventListener( 'resize', onWindowResize, false );
            
            this.cube(3);
            animate();      //渲染器
            mutually();          //交互事件
            
            
            function onWindowResize() {
    
                camera.aspect = container.clientWidth / container.clientHeight;
                camera.updateProjectionMatrix();
        
                renderer.setSize( container.clientWidth, container.clientHeight );
        
            }
    
            function animate() {
    
                requestAnimationFrame( animate );
                renderer.render( scene, camera );
            }
            
            //交互事件
            function mutually(){
                
                //初始化鼠标事件
                var event = new mouseEvents();
                event.init({domElement:scope.container});
                
                //绑定相关事件
                event.move.set(function(event){
                    scope.pickEnable()(event,function(target){
                        if(target == undefined){
                            recover();
                        }
                        if(target.length > 0 ){
                            var obj = target[0].object;
                            recover(obj);
                        }
        
                    })
                });
                
                event.down.set(function(event,target){
                    if(target==undefined)return;
                    if(target.offset || target.flag !== 0){
                        var name = scope.temporary.object.name;
                        var nor = scope.orientation[name].normal;
                        
                        
                    }
                    
                });
                
                event.up.set(function(event,target){
                    if(target.offset || target.flag !== 0){
                        var name = scope.temporary.object.name;
                        var cameraA = scope.camera;
                        var cameraB = scope.cameraCopy;
                        var position = scope.turnon(name);
                        if(position == undefined)return;
                        changeCamera(cameraA,position.hawk);
                        changeCamera(cameraB,position.scene);
                    }else{
                        return;
                    }
                    
                })
        
            }
            
            //更换模型颜色
            function recover(obj){
                var oldPro;
                if(obj == undefined){
                    oldPro = scope.temporary.object;
                    oldPro.material.color = scope.temporary.color;
                    scope.temporary.color = {};
                    scope.temporary.object = undefined;
                    scope.temporary.objName = [];
                }else{
                    var name = obj.name;
                    if(scope.temporary.objName.indexOf(name) == -1){
                        oldPro = scope.temporary.object;
                        if(oldPro!==undefined)oldPro.material.color = scope.temporary.color;
                        scope.temporary.color = obj.material.color;
                        scope.temporary.object = obj;
                        scope.temporary.objName = obj.name;
                        obj.material.color = new THREE.Color(0x91b8f9ab);
                    }else{
                    
                    }
                }
            }
            
            //联动交互
            function changeCamera(camera,pp){
                if(camera == undefined)return;
                camera.orbitControls.reset();
                camera.position.copy(pp);
                //camera.orbitControls.reset();
                camera.orbitControls.update();
                
                //缓动
                // if(scope.tween.aniamteCamera !== undefined){scope.tween.aniamteCamera(camera.position,pp,500,function(){
                //     camera.orbitControls.target.copy(new THREE.Vector3());
                //     camera.orbitControls.update();
                // })}else{
                //     camera.position.copy(pp);
                //     camera.orbitControls.target.copy(new THREE.Vector3());
                //     camera.orbitControls.update();
                // }
                
                
            }
            
            
        };
        
        //鹰眼模型生产器
        hawkW.prototype.cubeGeometry = function (type,measure) {
            var geo,geometry,material = new THREE.MeshBasicMaterial( {color: 0xffffff, side: 2} );
            switch (type){
                case "plane":
                    geometry = new THREE.PlaneGeometry(measure.w, measure.h, measure.d);
                    break;
                case "box":
                    geometry = new THREE.BoxGeometry(measure.w, measure.h, measure.d);
                    break;
                case "ring":
                    geometry = new THREE.RingGeometry(measure.w, measure.h, measure.d);
                    break;
                case "line":
                    geometry = new THREE.Geometry();
                    geometry.vertices = measure;
                    geo = new THREE.Line( geometry, new THREE.LineBasicMaterial( {color: 0x000000}) );
                    return geo;
                default:
                    geometry = new THREE.BoxGeometry(  measure.w, measure.h,measure.d);
                    break;
            }
            geo = new THREE.Mesh( geometry, material );
          return geo
        };
        
        //鹰眼模型组装线
        hawkW.prototype.cube = function(num) {
            
            var size = num || 4;
            var group  = this.machine(size);
            
            console.log(group)
        
        };
        
        //鹰眼模型图纸基地
        hawkW.prototype.machine = function (size) {
            
            if(size == undefined) return;
            var planGroup = new THREE.Group();
            var vertexGroup = new THREE.Group();
            var arrisGroup = new THREE.Group();
            var lineGroup = new THREE.Group();
            var ringGroup = new THREE.Group();
            var cube = new THREE.BoxGeometry(size,size,size);
                var vector = cube.vertices;
                var len =vector.length;
                var arris = [];
                var plane = [];
                var lines = [];
                var axisX = {},axisY = {},axisZ = {};
                var faceA ,faceB ,faceC,lineA,lineB,lineC,lineD;
            
            //顶点模型生成器
            for(var i = 0; i < len; i++){
                
                    //顶点模型生成器
                    var box = this.cubeGeometry("box",{w:1,h:1,d:1});
                    var vC = vector[i].clone();
                    var VP = vector[i].clone();
                        box.position.copy(vC);
                        box.name = "V"+i;
                        vertexGroup.add(box);
                        this.orientation[box.name] = {
                          normal: box.position.clone().sub(new THREE.Vector3(0,0,0)).divideScalar(box.position.clone().length())
                        };
                    switch (i){
                        case 0:
                            //棱模型数据
                            axisX["AX"+i] = {
                                Pp: new THREE.Vector3().addVectors(vector[i].clone(),vector[i+5].clone()).multiplyScalar(0.5),
                                len: [(size-1),1,1],
                                name:"AX"+i
                            };
                            axisY["AY"+i] = {
                                Pp: new THREE.Vector3().addVectors(vector[i].clone(),vector[i+2].clone()).multiplyScalar(0.5),
                                len: [1,(size-1),1],
                                name:"AY"+i
                            };
                            axisZ["AZ"+i] = {
                                Pp: new THREE.Vector3().addVectors(vector[i].clone(),vector[i+1].clone()).multiplyScalar(0.5),
                                len: [1,1,(size-1)],
                                name:"AZ"+i
                            };
                            arris.push(axisX["AX"+i],axisY["AY"+i],axisZ["AZ"+i]);
            
                            //面模型数据
                            faceA = {
                                Pp:new THREE.Vector3().addVectors(vector[i].clone(),vector[i+4].clone()).multiplyScalar(0.5).add(new THREE.Vector3(0,0.5,0)),
                                size: (size-1),
                                name:"Tf",
                                rotation:{x:-Math.PI/2,y:0,z:0}
                            };
                            faceB = {
                                Pp:new THREE.Vector3().addVectors(vector[i].clone(),vector[i+3].clone()).multiplyScalar(0.5).add(new THREE.Vector3(0.5,0,0)),
                                size: (size-1),
                                rotation:{x:0,y:Math.PI/2,z:0},
                                name:"Rf"
                            };
                            faceC = {
                                Pp:new THREE.Vector3().addVectors(vector[i].clone(),vector[i+7].clone()).multiplyScalar(0.5).add(new THREE.Vector3(0,0,0.5,)),
                                size: (size-1),
                                rotation:{x:0,y:0,z:0},
                                name:"Ff"
                            };
                            plane.push(faceA ,faceB ,faceC);
                            break;
                        case 3:
                            axisX["AX"+i] = {
                                Pp: new THREE.Vector3().addVectors(vector[i].clone(),vector[i+3].clone()).multiplyScalar(0.5),
                                len: [(size-1),1,1],
                                name:"AX"+i
                            };
                            axisY["AY"+i] = {
                                Pp: new THREE.Vector3().addVectors(vector[i].clone(),vector[i-2].clone()).multiplyScalar(0.5),
                                len: [1,(size-1),1],
                                name:"AY"+i
                            };
                            axisZ["AZ"+i] = {
                                Pp: new THREE.Vector3().addVectors(vector[i].clone(),vector[i-1].clone()).multiplyScalar(0.5),
                                len: [1,1,(size-1)],
                                name:"AZ"+i
                            };
                            arris.push(axisX["AX"+i],axisY["AY"+i],axisZ["AZ"+i]);
                            break;
                        case 4:
                            axisX["AX"+i] = {
                                Pp: new THREE.Vector3().addVectors(vector[i].clone(),vector[i-3].clone()).multiplyScalar(0.5),
                                len: [(size-1),1,1],
                                name:"AX"+i
                            };
                            axisY["AY"+i] = {
                                Pp: new THREE.Vector3().addVectors(vector[i].clone(),vector[i+2].clone()).multiplyScalar(0.5),
                                len: [1,(size-1),1],
                                name:"AY"+i
                            };
                            axisZ["AZ"+i] = {
                                Pp: new THREE.Vector3().addVectors(vector[i].clone(),vector[i+1].clone()).multiplyScalar(0.5),
                                len: [1,1,(size-1)],
                                name:"AZ"+i
                            };
                            arris.push(axisX["AX"+i],axisY["AY"+i],axisZ["AZ"+i]);
                            break;
                        case 6:
                            //面模型数据
                            faceA = {
                                Pp:new THREE.Vector3().addVectors(vector[i+1].clone(),vector[i-3].clone()).multiplyScalar(0.5).add(new THREE.Vector3(0,-0.5,0)),
                                size: (size-1),
                                rotation:{x:Math.PI/2,y:0,z:0},
                                name:"Df"
                            };
                            faceB = {
                                Pp:new THREE.Vector3().addVectors(vector[i].clone(),vector[i-1].clone()).multiplyScalar(0.5).add(new THREE.Vector3(-0.5,0,0)),
                                size: (size-1),
                                rotation:{x:0,y:-Math.PI/2,z:0},
                                name:"Lf"
                            };
                            faceC = {
                                Pp:new THREE.Vector3().addVectors(vector[i].clone(),vector[i-5].clone()).multiplyScalar(0.5).add(new THREE.Vector3(0,0,-0.5,)),
                                size: (size-1),
                                rotation:{x:0,y:Math.PI,z:0},
                                name:"Bf"
                            };
                            plane.push(faceA ,faceB ,faceC);
                            break;
                        case 7:
                            axisX["AX"+i] = {
                                Pp: new THREE.Vector3().addVectors(vector[i].clone(),vector[i-5].clone()).multiplyScalar(0.5),
                                len: [(size-1),1,1],
                                name:"AX"+i
                            };
                            axisY["AY"+i] = {
                                Pp: new THREE.Vector3().addVectors(vector[i].clone(),vector[i-2].clone()).multiplyScalar(0.5),
                                len: [1,(size-1),1],
                                name:"AY"+i
                            };
                            axisZ["AZ"+i] = {
                                Pp: new THREE.Vector3().addVectors(vector[i].clone(),vector[i-1].clone()).multiplyScalar(0.5),
                                len: [1,1,(size-1)],
                                name:"AZ"+i
                            };
                            arris.push(axisX["AX"+i],axisY["AY"+i],axisZ["AZ"+i]);
                            break;
                    }
                        VP.multiplyScalar(1.34);
                        lines.push(VP);
                this.targetArr.push(box);
                }
                
            //棱模型生成器
            for (var k = 0; k < arris.length; k++ ){
                   var object = arris[k];
                   var position = object.Pp;
                var box = this.cubeGeometry("box",{w:object.len[0],h:object.len[1],d:object.len[2]});
                    box.position.copy(position.clone());
                    box.name = object.name;
                arrisGroup.add(box);
                this.orientation[box.name] = {
                    normal: box.position.clone().sub(new THREE.Vector3(0,0,0)).divideScalar(box.position.clone().length())
                };
                this.targetArr.push(box);
            }
            
            //面模型生成器
            for (var m = 0; m < plane.length; m++ ){
                var object = plane[m];
                var position = object.Pp;
                var box = this.cubeGeometry("plane",{w:object.size,h:object.size,d:object.size});
                    box.name = object.name;
                var texture = new THREE.TextureLoader().load( this.way+box.name+'.jpg' );
                box.material.map = texture;
                box.position.copy(position.clone());
                box.rotation.set(object.rotation.x,object.rotation.y,object.rotation.z);
                this.orientation[box.name] = {
                    normal: box.position.clone().sub(new THREE.Vector3(0,0,0)).divideScalar(box.position.clone().length())
                };
                planGroup.add(box);
                this.targetArr.push(box);
            }
            
            //底环生成器
            if(vector){
                var box = this.cubeGeometry("ring",{w:3,h:3.5,d:48});
                box.position.setY(-2.0);
                box.rotation.set(-Math.PI/2,0,0);
                box.name = "ring";
                this.orientation[box.name] = {
                  normal:new THREE.Vector3()
                };
                ringGroup.add(box);
                this.targetArr.push(box);
            }
    
            lineA = this.cubeGeometry("line",[lines[5],lines[0],lines[1],lines[4],lines[5],lines[7],lines[6],lines[3],lines[2],lines[7]]);
            lineB = this.cubeGeometry("line",[lines[0],lines[2]]);
            lineC = this.cubeGeometry("line",[lines[1],lines[3]]);
            lineD = this.cubeGeometry("line",[lines[4],lines[6]]);

            lineGroup.add(lineA,lineB,lineC,lineD);
            //添加进场景
            this.scene.add(planGroup,vertexGroup,arrisGroup,lineGroup,ringGroup);
            return [planGroup,vertexGroup,arrisGroup,lineGroup,ringGroup];
            
        };
        
        //鹰眼拾取
        hawkW.prototype.pickEnable = function() {
            var scope = this;
            return function (event,callback) {
                if(!scope.enable)return;
                var ray = new THREE.Raycaster();
                var mouse = new THREE.Vector2();
                var bbox = scope.container.children[0].getBoundingClientRect();
                 var cc = {
                     x: (event.clientX - bbox.left) * (scope.container.clientWidth / bbox.width),
                     y: (event.clientY - bbox.top) * (scope.container.clientHeight / bbox.height)
                 };
                mouse.x = (cc.x / scope.container.clientWidth) * 2 - 1;
                mouse.y = -(cc.y / scope.container.clientHeight) * 2 + 1;
                ray.setFromCamera(mouse,scope.camera);
                
                var backObject = ray.intersectObjects(scope.targetArr);
                callback && callback(backObject);
                return backObject;
                
                
            };
           
            
        };
        
        //鹰眼交互
        hawkW.prototype.turnon = function(obj){
            
            if(obj == undefined || obj == "ring")return;
            var nor = this.orientation[obj].normal;
            var lenA = this.origin.haw.length();
            var lenB = this.origin.scene.length();
            var PpA = nor.clone().multiplyScalar(lenA).clone();
            var PpB = nor.clone().multiplyScalar(lenB).clone();
            return {
                hawk: PpA.clone(),
                scene: PpB.clone()
            };
        };
        
    
    return new hawkW();
    
});